/*
 * MainCanvas.java
 *
 * Created on June 7, 2007, 9:42 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package flashomatic;

import java.util.Timer;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Canvas;
import java.util.*;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.game.Sprite;

/**
 *
 * @author Administrator
 */
class FlashomaticCanvas extends Canvas implements Runnable {
  
  int stackIndex = -1;
  int screenHeight = 320;
  int screenWidth = 240;
  static Flashomatic m = null;
  
  String currentCharacter = null;
  String currentPinyin = null;
  String currentDefinition = null;
  
  boolean showSimplified = true;
  boolean showPinyin = false;
  boolean showDefinition = false;
  
  Vector knowledge;
  
  int knownCount = 0;
  
  
  Vector stack = null;
  String stackName;
  FlashItem word = null;
  
  Vector definitionLines = null;
  Vector unknownWords;
  
  Font smallFont;
  Font largeFont;
  Font smallFontBold;
  Font largeFontBold;
  boolean networkActive = false;
  
  public static final int KEY_UP = 33;
  public static final int KEY_DOWN = 34;
  public static final int KEY_LEFT = 35;
  public static final int KEY_RIGHT = 36;
  public static final int KEY_RSOFT = 37;
  public static final int KEY_LSOFT = 38;
  public static final int KEY_MENU = 39;
  public static final int KEY_CANCEL = 42;
  public static final int KEY_SELECT = 43;
  
  
  /** Creates a new instance of MainCanvas */
  public FlashomaticCanvas() {
    
    setFullScreenMode(true);
    
    screenHeight = getHeight();
    screenWidth = getWidth();
    
    smallFont = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_PLAIN,Font.SIZE_SMALL);
    largeFont = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_PLAIN,Font.SIZE_LARGE);
    
    smallFontBold = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_BOLD,Font.SIZE_SMALL);
    largeFontBold = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_BOLD,Font.SIZE_LARGE);
    
    knowledge = new Vector();
    
  }
  
  public void setStack(String s) {
    
    if (s != null) stackName = s;
    
    this.stackIndex = -1;
    
    MMParser p = new MMParser(stackName);
    stack = p.readTxt();
    
    // Build the list of unknown words
    unknownWords = new Vector();
    for (int x=0;x<stack.size();x++) {
      getWord(x);
      if (! knowledge.contains(word.pinyin)) {
        unknownWords.addElement(Integer.toString(x));
        System.out.print("-"+x);
      }
    }
    
    getNextWord();
  }
  
  public static void setMidlet(Flashomatic midlet) {
    m = midlet;
  }
  
  public void start() {
    Thread runner = new Thread(this);
    runner.start();
  }
  
  public void run() {
    
    System.out.println("Canvas Running");
    
    while(true) {
      
      // Just in case the screen changes size
      screenHeight = getHeight();
      screenWidth = getWidth();
      
      repaint();
      
      System.gc();
      
      // Sleep between refreshes
      try {
        Thread.currentThread().sleep(50);
      } catch(Exception e) {}
    }
  }
  
  public void getWord(int index) {
    
    //System.out.println("Getting a word");
    
    // Read the word
    String s = (String)stack.elementAt(index);
    
    String[] items = new String[4];
    int z = 0;
    
    String x= new String();
    
    for(int i=0; i<s.length();i++){
      
      if (s.charAt(i)=='\t'){
        
        if (z > 4) { break; }
        
        items[z] = x.trim();
        z += 1;
        x = new String();
        
      } else {
        x+=s.charAt(i);
      }
    }
    items[3] = x.trim();
    
    word = new FlashItem(items[0], items[1], items[2], items[3], getWidth() - 20, smallFont);
    
    //System.out.println("Knowledge db is "+knowledge.size()+" words");
    
    if (knowledge != null && knowledge.contains(word.pinyin)) {
      
      //System.out.println("Knows word: "+word.pinyin);
      word.known = true;
      
    } else {
      
      word.known = false;
      //System.out.println("Doesn't know word: "+word.pinyin);
    }
  }
  
  public void getNextWord() {
    
    if (unknownWords.size() == 0) return;
    
    Random r = new Random();
    int count = 0;
    
    int current = stackIndex;
    int a;
    
    while (true) {
      
      a = Math.abs(r.nextInt() % (unknownWords.size()));
      stackIndex = Integer.parseInt(unknownWords.elementAt(a).toString());
      
      if (unknownWords.size() > 1 && current == stackIndex) {
        System.out.println("Selected the same word twice");
        continue;
      } else {
        break;
      }
    }

    System.out.println("Showing word: "+stackIndex);
    
    getWord(stackIndex);
    
    showPinyin = false;
    showDefinition = false;
  }
  
  // Key pressed events
  public void keyPressed(int keyCode) {
    
    int gameCode = 0;
    try {
      gameCode = getGameAction(keyCode);
    } catch (Exception e){}
    
    int keyPress = -1;
    
    // Check codes
    switch (keyCode){
      
      case -7:
      case 22:
      case -22:
      case -203:
        keyPress = KEY_RSOFT;
        break;
      case -6:
      case 21:
      case -21:
      case -202:
        keyPress = KEY_LSOFT;
        break;
      case 23:
      case -23:
        keyPress = KEY_MENU;
        break;
      case -5:
      case -26:
      case -20:
        keyPress = KEY_SELECT;
        break;
      case -204:
      case -16:
        keyPress = KEY_CANCEL;
        break;
        
    }
    
    // Check directional if still no key found
    if (keyPress == -1){
      switch (gameCode){
        case Canvas.UP:
          keyPress = KEY_UP;
          break;
        case Canvas.DOWN:
          keyPress = KEY_DOWN;
          break;
        case Canvas.LEFT:
          keyPress = KEY_LEFT;
          break;
        case Canvas.RIGHT:
          keyPress = KEY_RIGHT;
          break;
      }
    }
    
    switch (keyPress) {
      
      case KEY_UP:
        // Knew character
        if (! word.known) {
          //System.out.println("User claims they know "+word.pinyin);
          knowledge.addElement(word.pinyin);
          try { unknownWords.removeElement(Integer.toString(stackIndex)); } catch (Exception e) {}
          knownCount += 1;
          word.known = true;
        }
        //getNextWord();
        break;
        
      case KEY_DOWN:
        // Did not know character
        if (word.known){
          knowledge.removeElement(word.pinyin);
          word.known = false;
          try {
            if (! unknownWords.contains(Integer.toString(stackIndex))) {
              unknownWords.addElement(Integer.toString(stackIndex));
            }
          } catch (Exception e) {}
          knownCount -= 1;
        }
       // getNextWord();
        break;
        
      case KEY_LEFT:
        // Previous Character
        if (stackIndex >= 1) {
          this.stackIndex -= 1;
          getWord(stackIndex);
          showPinyin = true;
          showDefinition = true;
        }
        break;
        
      case KEY_RIGHT:
        // Next Character
        if (stackIndex < stack.size() - 1) {
          this.stackIndex += 1;
        } else {
          this.stackIndex = 0;
        }
        getWord(stackIndex);
        showPinyin = true;
        showDefinition = true;
        break;
        
      case KEY_LSOFT:
        // Main Menu
        m.getDisplay().setCurrent(m.get_mainMenu());
        break;
        
      case KEY_RSOFT:
        // Main Menu
        m.exitMIDlet();
        break;
        
      case KEY_SELECT:
        // Show Pinyin/Definition
        if (! showPinyin) {
          showPinyin = true;
        } else if (! showDefinition) {
          showDefinition = true;
        } else if (stackIndex < stack.size()) {
          getNextWord();
        }
        break;
    }
    repaint();
  }
  
  
  public void paint(Graphics g) {
    
    //System.out.println("Painting");
    // Clear the background
    g.setClip(0, 0, getWidth(), getHeight());
    
    // Draw the background
    g.setColor(0x000000);
    g.fillRect(0,0,getWidth(),getHeight());
    
    g.setColor(0xAAAAAA);
    g.setFont(smallFont);
    g.drawString("Flashomatic "+(stackIndex+1)+" of "+stack.size(),5,5, Graphics.TOP|Graphics.LEFT);
    
    int y = 3 * largeFont.getHeight();
    
    // Draw Character
    g.setFont(largeFontBold);
    
    if (word.known) {
      g.setColor(0x77FF77);
    } else {
      g.setColor(0xFF7777);
    }
    
    if (showSimplified) {
      g.drawString(word.getSimplified(), getWidth()/2, y, Graphics.TOP|Graphics.HCENTER);
    } else {
      g.drawString(word.getTraditional(), getWidth()/2, y, Graphics.TOP|Graphics.HCENTER);
    }
    
    y += largeFontBold.getHeight() + 20;
    
    if (showPinyin) {
      
      g.setColor(0x444444);
      g.fillRoundRect(5,y-5,getWidth()-10,largeFont.getHeight()+10,5,5);
      
      // Draw Pinyin
      g.setFont(largeFont);
      g.setColor(0xFFFFFF);
      
      g.drawString(word.getPinyin(), getWidth()/2, y, Graphics.TOP|Graphics.HCENTER);
      y += largeFont.getHeight() + 10;
      // Draw Definition Lines
      
    }
    
    if (showDefinition) {
      
      y+=10;
      
      g.setColor(0x444444);
      g.fillRoundRect(5,y-5,getWidth()-10,(smallFont.getHeight()*word.definition.size())+10,5,5);
      
      g.setFont(smallFont);
      g.setColor(0xFFFFFF);
      
      for (int i = 0; i < word.definition.size(); ++i) {
        
        g.drawString((String)word.definition.elementAt(i), getWidth()/2, y, Graphics.TOP|Graphics.HCENTER);
        y += smallFont.getHeight();
      }
    }
    
    g.setFont(smallFontBold);
    g.setColor(0xAAAAAA);
    
    g.drawString(knowledge.size()+"+ "+unknownWords.size()+"-", getWidth()/2, getHeight()-5, Graphics.HCENTER|Graphics.BOTTOM);
    g.drawString("Menu", 10, getHeight()-5, Graphics.LEFT|Graphics.BOTTOM);
    g.drawString("Exit", getWidth()-10, getHeight()-5, Graphics.RIGHT|Graphics.BOTTOM);
  }
}

